package com.vehiclemanagement.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vehiclemanagement.entity.MaintenanceRecord;
import com.vehiclemanagement.entity.Vehicle;
import com.vehiclemanagement.mapper.MaintenanceRecordMapper;
import com.vehiclemanagement.mapper.VehicleMapper;
import com.vehiclemanagement.service.MaintenanceRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.Year;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 车辆维修保养记录服务实现类
 */
@Service
@Slf4j
public class MaintenanceRecordServiceImpl extends ServiceImpl<MaintenanceRecordMapper, MaintenanceRecord> implements MaintenanceRecordService {

    @Autowired
    private VehicleMapper vehicleMapper;

    @Override
    public IPage<MaintenanceRecord> pageMaintenanceRecords(Integer current, Integer size, String searchTerm,
                                                        Long vehicleId, Integer maintenanceType, Integer status,
                                                        LocalDateTime startTime, LocalDateTime endTime) {
        log.info("分页查询维修保养记录: current={}, size={}, searchTerm={}, vehicleId={}, maintenanceType={}, status={}, startTime={}, endTime={}",
                current, size, searchTerm, vehicleId, maintenanceType, status, startTime, endTime);
                
        Page<MaintenanceRecord> page = new Page<>(current, size);
        
        // 构建查询条件
        StringBuilder whereSql = new StringBuilder();
        whereSql.append(" m.del_flag = 0 ");
        
        // 添加搜索条件
        if (StringUtils.hasText(searchTerm)) {
            whereSql.append(" AND (v.plate_number LIKE '%").append(searchTerm).append("%'")
                    .append(" OR m.maintenance_content LIKE '%").append(searchTerm).append("%'")
                    .append(" OR m.maintenance_company LIKE '%").append(searchTerm).append("%')");
        }
        
        // 添加车辆ID查询条件
        if (vehicleId != null) {
            whereSql.append(" AND m.vehicle_id = ").append(vehicleId);
        }
        
        // 添加维修保养类型查询条件
        if (maintenanceType != null) {
            whereSql.append(" AND m.maintenance_type = ").append(maintenanceType);
        }
        
        // 添加状态查询条件
        if (status != null) {
            whereSql.append(" AND m.status = ").append(status);
        }
        
        // 添加时间范围查询条件
        if (startTime != null) {
            whereSql.append(" AND m.start_time >= '").append(startTime).append("'");
        }
        
        if (endTime != null) {
            whereSql.append(" AND m.start_time <= '").append(endTime).append("'");
        }
        
        try {
            return baseMapper.selectPageWithInfo(page, whereSql.toString());
        } catch (Exception e) {
            log.error("分页查询维修保养记录失败", e);
            return new Page<>();
        }
    }

    @Override
    public MaintenanceRecord getMaintenanceRecordById(Long id) {
        log.info("根据ID获取维修保养记录: id={}", id);
        
        if (id == null) {
            log.error("获取维修保养记录失败：ID为空");
            return null;
        }
        
        try {
            // 构建查询条件
            String whereSql = " m.id = " + id + " AND m.del_flag = 0";
            Page<MaintenanceRecord> page = new Page<>(1, 1);
            IPage<MaintenanceRecord> recordPage = baseMapper.selectPageWithInfo(page, whereSql);
            
            if (recordPage.getRecords().isEmpty()) {
                log.warn("未找到ID为{}的维修保养记录", id);
                return null;
            }
            
            return recordPage.getRecords().get(0);
        } catch (Exception e) {
            log.error("获取维修保养记录失败: id={}", id, e);
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addMaintenanceRecord(MaintenanceRecord record) {
        log.info("添加维修保养记录: {}", record);
        
        if (record == null) {
            log.error("添加维修保养记录失败：记录为空");
            return false;
        }
        
        try {
            // 设置默认值
            LocalDateTime now = LocalDateTime.now();
            record.setCreateTime(now);
            record.setUpdateTime(now);
            record.setDelFlag(0);
            
            // 如果状态为空，设置为未开始(0)
            if (record.getStatus() == null) {
                record.setStatus(0);
            }
            
            // 如果设置了费用相关字段，计算总费用和实际支出
            if (record.getMaintenanceCost() != null || record.getPartsCost() != null || record.getLaborCost() != null) {
                BigDecimal maintenanceCost = record.getMaintenanceCost() != null ? record.getMaintenanceCost() : BigDecimal.ZERO;
                BigDecimal partsCost = record.getPartsCost() != null ? record.getPartsCost() : BigDecimal.ZERO;
                BigDecimal laborCost = record.getLaborCost() != null ? record.getLaborCost() : BigDecimal.ZERO;
                
                // 计算总费用
                BigDecimal totalCost = calculateTotalCost(maintenanceCost, partsCost, laborCost);
                record.setTotalCost(totalCost);
                
                // 计算实际支出
                BigDecimal insuranceClaimAmount = record.getInsuranceClaimAmount() != null ? record.getInsuranceClaimAmount() : BigDecimal.ZERO;
                BigDecimal actualCost = calculateActualCost(totalCost, insuranceClaimAmount);
                record.setActualCost(actualCost);
            }
            
            // 设置维修保养里程为当前车辆里程（如果未设置）
            if (record.getMaintenanceMileage() == null && record.getVehicleId() != null) {
                Vehicle vehicle = vehicleMapper.selectById(record.getVehicleId());
                if (vehicle != null && vehicle.getCurrentMileage() != null) {
                    record.setMaintenanceMileage(vehicle.getCurrentMileage());
                }
            }
            
            // 保存记录
            boolean result = save(record);
            
            // 如果状态为进行中，更新车辆状态为维修中
            if (result && record.getStatus() != null && record.getStatus() == 1 && record.getVehicleId() != null) {
                updateVehicleStatus(record.getVehicleId(), 2); // 2=维修中
            }
            
            return result;
        } catch (Exception e) {
            log.error("添加维修保养记录失败", e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateMaintenanceRecord(MaintenanceRecord record) {
        log.info("更新维修保养记录: {}", record);
        
        if (record == null || record.getId() == null) {
            log.error("更新维修保养记录失败：记录为空或ID为空");
            return false;
        }
        
        try {
            // 获取原记录
            MaintenanceRecord originalRecord = getById(record.getId());
            if (originalRecord == null) {
                log.error("更新维修保养记录失败：找不到ID为{}的记录", record.getId());
                return false;
            }
            
            // 更新时间
            record.setUpdateTime(LocalDateTime.now());
            
            // 如果更新了费用相关字段，重新计算总费用和实际支出
            if (record.getMaintenanceCost() != null || record.getPartsCost() != null || record.getLaborCost() != null) {
                BigDecimal maintenanceCost = record.getMaintenanceCost() != null ? record.getMaintenanceCost() : originalRecord.getMaintenanceCost();
                BigDecimal partsCost = record.getPartsCost() != null ? record.getPartsCost() : originalRecord.getPartsCost();
                BigDecimal laborCost = record.getLaborCost() != null ? record.getLaborCost() : originalRecord.getLaborCost();
                
                if (maintenanceCost != null || partsCost != null || laborCost != null) {
                    // 确保没有null值
                    maintenanceCost = maintenanceCost != null ? maintenanceCost : BigDecimal.ZERO;
                    partsCost = partsCost != null ? partsCost : BigDecimal.ZERO;
                    laborCost = laborCost != null ? laborCost : BigDecimal.ZERO;
                    
                    // 计算总费用
                    BigDecimal totalCost = calculateTotalCost(maintenanceCost, partsCost, laborCost);
                    record.setTotalCost(totalCost);
                    
                    // 计算实际支出
                    BigDecimal insuranceClaimAmount = record.getInsuranceClaimAmount() != null ? 
                            record.getInsuranceClaimAmount() : 
                            (originalRecord.getInsuranceClaimAmount() != null ? originalRecord.getInsuranceClaimAmount() : BigDecimal.ZERO);
                    BigDecimal actualCost = calculateActualCost(totalCost, insuranceClaimAmount);
                    record.setActualCost(actualCost);
                }
            }
            
            // 更新记录
            boolean result = updateById(record);
            
            // 如果状态从其他状态变更为进行中，更新车辆状态为维修中
            if (result && record.getStatus() != null && record.getStatus() == 1 && 
                (originalRecord.getStatus() == null || originalRecord.getStatus() != 1) && 
                record.getVehicleId() != null) {
                updateVehicleStatus(record.getVehicleId(), 2); // 2=维修中
            }
            
            // 如果状态从进行中变更为已完成，更新车辆状态为空闲
            if (result && record.getStatus() != null && record.getStatus() == 2 && 
                originalRecord.getStatus() != null && originalRecord.getStatus() == 1 && 
                record.getVehicleId() != null) {
                updateVehicleStatus(record.getVehicleId(), 0); // 0=空闲
            }
            
            return result;
        } catch (Exception e) {
            log.error("更新维修保养记录失败: id={}", record.getId(), e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteMaintenanceRecord(Long id) {
        log.info("删除维修保养记录: id={}", id);
        
        if (id == null) {
            log.error("删除维修保养记录失败：ID为空");
            return false;
        }
        
        try {
            // 获取原记录
            MaintenanceRecord record = getById(id);
            if (record == null) {
                log.error("删除维修保养记录失败：找不到ID为{}的记录", id);
                return false;
            }
            
            // 如果记录状态为进行中，需要恢复车辆状态为空闲
            if (record.getStatus() != null && record.getStatus() == 1 && record.getVehicleId() != null) {
                updateVehicleStatus(record.getVehicleId(), 0); // 0=空闲
            }
            
            // 逻辑删除
            record.setDelFlag(1);
            record.setUpdateTime(LocalDateTime.now());
            
            return updateById(record);
        } catch (Exception e) {
            log.error("删除维修保养记录失败: id={}", id, e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean startMaintenance(Long id) {
        log.info("开始维修保养: id={}", id);
        
        if (id == null) {
            log.error("开始维修保养失败：ID为空");
            return false;
        }
        
        try {
            // 获取原记录
            MaintenanceRecord record = getById(id);
            if (record == null) {
                log.error("开始维修保养失败：找不到ID为{}的记录", id);
                return false;
            }
            
            // 检查状态是否为未开始
            if (record.getStatus() != null && record.getStatus() != 0) {
                log.error("开始维修保养失败：记录状态不是'未开始'，当前状态={}", record.getStatus());
                return false;
            }
            
            // 更新记录状态为进行中
            record.setStatus(1);
            record.setStartTime(LocalDateTime.now());
            record.setUpdateTime(LocalDateTime.now());
            
            boolean result = updateById(record);
            
            // 更新车辆状态为维修中
            if (result && record.getVehicleId() != null) {
                updateVehicleStatus(record.getVehicleId(), 2); // 2=维修中
            }
            
            return result;
        } catch (Exception e) {
            log.error("开始维修保养失败: id={}", id, e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeMaintenance(Long id, LocalDateTime endTime, BigDecimal maintenanceCost, 
                                    BigDecimal partsCost, BigDecimal laborCost, Integer isInsuranceClaim, 
                                    BigDecimal insuranceClaimAmount, String remark) {
        log.info("完成维修保养: id={}, endTime={}, maintenanceCost={}, partsCost={}, laborCost={}, isInsuranceClaim={}, insuranceClaimAmount={}, remark={}",
                id, endTime, maintenanceCost, partsCost, laborCost, isInsuranceClaim, insuranceClaimAmount, remark);
        
        if (id == null) {
            log.error("完成维修保养失败：ID为空");
            return false;
        }
        
        try {
            // 获取原记录
            MaintenanceRecord record = getById(id);
            if (record == null) {
                log.error("完成维修保养失败：找不到ID为{}的记录", id);
                return false;
            }
            
            // 检查状态是否为进行中
            if (record.getStatus() == null || record.getStatus() != 1) {
                log.error("完成维修保养失败：记录状态不是'进行中'，当前状态={}", record.getStatus());
                return false;
            }
            
            // 设置结束时间，如果未提供则使用当前时间
            record.setEndTime(endTime != null ? endTime : LocalDateTime.now());
            
            // 设置费用相关字段
            record.setMaintenanceCost(maintenanceCost != null ? maintenanceCost : BigDecimal.ZERO);
            record.setPartsCost(partsCost != null ? partsCost : BigDecimal.ZERO);
            record.setLaborCost(laborCost != null ? laborCost : BigDecimal.ZERO);
            
            // 计算总费用
            BigDecimal totalCost = calculateTotalCost(record.getMaintenanceCost(), record.getPartsCost(), record.getLaborCost());
            record.setTotalCost(totalCost);
            
            // 设置保险理赔相关字段
            record.setIsInsuranceClaim(isInsuranceClaim != null ? isInsuranceClaim : 0);
            record.setInsuranceClaimAmount(insuranceClaimAmount != null && isInsuranceClaim != null && isInsuranceClaim == 1 ? 
                    insuranceClaimAmount : BigDecimal.ZERO);
            
            // 计算实际支出
            BigDecimal actualCost = calculateActualCost(totalCost, record.getInsuranceClaimAmount());
            record.setActualCost(actualCost);
            
            // 设置备注
            if (StringUtils.hasText(remark)) {
                record.setRemark(remark);
            }
            
            // 更新状态为已完成
            record.setStatus(2);
            record.setUpdateTime(LocalDateTime.now());
            
            boolean result = updateById(record);
            
            // 更新车辆状态为空闲
            if (result && record.getVehicleId() != null) {
                updateVehicleStatus(record.getVehicleId(), 0); // 0=空闲
            }
            
            return result;
        } catch (Exception e) {
            log.error("完成维修保养失败: id={}", id, e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelMaintenance(Long id, String remark) {
        log.info("取消维修保养: id={}, remark={}", id, remark);
        
        if (id == null) {
            log.error("取消维修保养失败：ID为空");
            return false;
        }
        
        try {
            // 获取原记录
            MaintenanceRecord record = getById(id);
            if (record == null) {
                log.error("取消维修保养失败：找不到ID为{}的记录", id);
                return false;
            }
            
            // 检查状态是否为未开始或进行中
            if (record.getStatus() == null || record.getStatus() > 1) {
                log.error("取消维修保养失败：记录状态不是'未开始'或'进行中'，当前状态={}", record.getStatus());
                return false;
            }
            
            // 设置备注
            if (StringUtils.hasText(remark)) {
                record.setRemark(remark);
            }
            
            // 更新状态为已取消
            record.setStatus(3);
            record.setUpdateTime(LocalDateTime.now());
            
            boolean result = updateById(record);
            
            // 如果是从进行中状态取消，需要更新车辆状态为空闲
            if (result && record.getStatus() == 1 && record.getVehicleId() != null) {
                updateVehicleStatus(record.getVehicleId(), 0); // 0=空闲
            }
            
            return result;
        } catch (Exception e) {
            log.error("取消维修保养失败: id={}", id, e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    public BigDecimal calculateTotalCost(BigDecimal maintenanceCost, BigDecimal partsCost, BigDecimal laborCost) {
        // 确保没有null值
        maintenanceCost = maintenanceCost != null ? maintenanceCost : BigDecimal.ZERO;
        partsCost = partsCost != null ? partsCost : BigDecimal.ZERO;
        laborCost = laborCost != null ? laborCost : BigDecimal.ZERO;
        
        // 计算总费用
        return maintenanceCost.add(partsCost).add(laborCost);
    }

    @Override
    public BigDecimal calculateActualCost(BigDecimal totalCost, BigDecimal insuranceClaimAmount) {
        // 确保没有null值
        totalCost = totalCost != null ? totalCost : BigDecimal.ZERO;
        insuranceClaimAmount = insuranceClaimAmount != null ? insuranceClaimAmount : BigDecimal.ZERO;
        
        // 计算实际支出（总费用-保险理赔金额），不能小于零
        BigDecimal actualCost = totalCost.subtract(insuranceClaimAmount);
        return actualCost.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : actualCost;
    }

    @Override
    public BigDecimal sumTotalCostByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("获取车辆维修保养总费用失败：车辆ID为空");
            return BigDecimal.ZERO;
        }
        
        try {
            BigDecimal totalCost = baseMapper.sumTotalCostByVehicleId(vehicleId);
            return totalCost != null ? totalCost : BigDecimal.ZERO;
        } catch (Exception e) {
            log.error("获取车辆维修保养总费用失败: vehicleId={}", vehicleId, e);
            return BigDecimal.ZERO;
        }
    }

    @Override
    public BigDecimal sumActualCostByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("获取车辆维修保养实际支出总费用失败：车辆ID为空");
            return BigDecimal.ZERO;
        }
        
        try {
            BigDecimal actualCost = baseMapper.sumActualCostByVehicleId(vehicleId);
            return actualCost != null ? actualCost : BigDecimal.ZERO;
        } catch (Exception e) {
            log.error("获取车辆维修保养实际支出总费用失败: vehicleId={}", vehicleId, e);
            return BigDecimal.ZERO;
        }
    }

    @Override
    public Integer countMaintenanceByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("获取车辆维修保养次数失败：车辆ID为空");
            return 0;
        }
        
        try {
            Integer count = baseMapper.countMaintenanceByVehicleId(vehicleId);
            return count != null ? count : 0;
        } catch (Exception e) {
            log.error("获取车辆维修保养次数失败: vehicleId={}", vehicleId, e);
            return 0;
        }
    }

    @Override
    public List<Map<String, Object>> statisticsByType(LocalDateTime startTime, LocalDateTime endTime) {
        log.info("按维修保养类型统计: startTime={}, endTime={}", startTime, endTime);
        
        try {
            // 如果未提供时间范围，使用当前年份
            if (startTime == null || endTime == null) {
                int currentYear = Year.now().getValue();
                startTime = LocalDateTime.of(currentYear, 1, 1, 0, 0, 0);
                endTime = LocalDateTime.of(currentYear, 12, 31, 23, 59, 59);
            }
            
            // 获取统计数据
            List<Map<String, Object>> result = baseMapper.statisticsByType(startTime, endTime);
            
            // 添加维修保养类型名称
            for (Map<String, Object> item : result) {
                Integer type = (Integer) item.get("maintenance_type");
                item.put("maintenance_type_name", getMaintenanceTypeName(type));
            }
            
            return result;
        } catch (Exception e) {
            log.error("按维修保养类型统计失败", e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<Map<String, Object>> statisticsByMonth(Integer year) {
        log.info("按月份统计维修保养费用: year={}", year);
        
        try {
            // 如果未提供年份，使用当前年份
            if (year == null) {
                year = Year.now().getValue();
            }
            
            // 获取统计数据
            return baseMapper.statisticsByMonth(year);
        } catch (Exception e) {
            log.error("按月份统计维修保养费用失败: year={}", year, e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<Map<String, Object>> findVehiclesNeedingMaintenance(Double mileageThreshold) {
        log.info("查询即将到期需要保养的车辆: mileageThreshold={}", mileageThreshold);
        
        try {
            // 如果未提供里程数阈值，使用默认值5000公里
            if (mileageThreshold == null || mileageThreshold <= 0) {
                mileageThreshold = 5000.0;
            }
            
            // 查询需要保养的车辆
            return baseMapper.findVehiclesNeedingMaintenance(mileageThreshold);
        } catch (Exception e) {
            log.error("查询即将到期需要保养的车辆失败: mileageThreshold={}", mileageThreshold, e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 更新车辆状态
     *
     * @param vehicleId 车辆ID
     * @param status    状态：0-空闲，1-使用中，2-维修中
     * @return 是否成功
     */
    private boolean updateVehicleStatus(Long vehicleId, Integer status) {
        if (vehicleId == null || status == null) {
            return false;
        }
        
        try {
            Vehicle vehicle = vehicleMapper.selectById(vehicleId);
            if (vehicle == null) {
                log.error("更新车辆状态失败：找不到ID为{}的车辆", vehicleId);
                return false;
            }
            
            vehicle.setStatus(status);
            vehicle.setUpdateTime(LocalDateTime.now());
            
            return vehicleMapper.updateById(vehicle) > 0;
        } catch (Exception e) {
            log.error("更新车辆状态失败: vehicleId={}, status={}", vehicleId, status, e);
            return false;
        }
    }
    
    /**
     * 获取维修保养类型名称
     *
     * @param type 维修保养类型
     * @return 维修保养类型名称
     */
    private String getMaintenanceTypeName(Integer type) {
        if (type == null) {
            return "未知类型";
        }
        
        switch (type) {
            case 1: return "定期保养";
            case 2: return "故障维修";
            case 3: return "事故维修";
            case 4: return "保险理赔维修";
            case 5: return "其他";
            default: return "未知类型";
        }
    }
} 